// i.r(t),
//   i.d(t, { GetFloorIntersectCommand: () => n.Z, default: () => b })

import { GetFloorIntersectCommand } from "../command/floor.command"
import Module from "./Module"
import SymbolList from "../SymbolList"
import CameraData from "../data/CameraData"
import l from "../math/27687"
import FloorsData from "../data/FloorsData"
import ViewmodeData from "../data/ViewmodeData"
import RaycasterModule from "./RaycasterModule"
import { roomFunc } from "../utils/room.util"
import ModelColliderTarget from "../mesh/ModelColliderTarget"
import f from "../math/69626"
import * as THREE from "three"
import Vectors from "../three/Vectors"
import funcUtil from "../utils/func.util"
import { phaseState } from "../enum/phase.enum"
import viewmodeEnum from "../enum/viewmode.enum"
import WebGLRendererModule from "./WebGLRendererModule"
import { Camera } from "three"
import EngineContext from "../EngineContext"

export default class FloorCaster extends Module {
  cameraPosition: THREE.Vector3
  forwardPosition: THREE.Vector3
  targetPlane: THREE.Plane
  engine: EngineContext
  renderer: WebGLRendererModule
  cameraData: CameraData
  viewmodeData: ViewmodeData
  raycaster: RaycasterModule
  floorsData: FloorsData
  constructor() {
    super(...arguments)
    this.name = "floor-caster"
    this.cameraPosition = new THREE.Vector3()
    this.forwardPosition = new THREE.Vector3()
    this.targetPlane = new THREE.Plane()
  }
  async init(e, t) {
    this.engine = t
    ;[this.renderer, this.cameraData, this.viewmodeData, this.raycaster, this.floorsData] = await Promise.all([
      t.getModuleBySymbol(SymbolList.WEBGL_RENDERER),
      t.market.waitForData(CameraData),
      t.market.waitForData(ViewmodeData),
      t.getModule(RaycasterModule),
      t.market.waitForData(FloorsData)
    ])
    t.commandBinder.addBinding(GetFloorIntersectCommand, e => this.castToFloor(e.screenPosition, e.height, e.includeHiddenFloors))
  }
  async castToFloor(e, t, i = !0) {
    await this.engine.after(phaseState.End)
    const n = this.renderer.getScene().camera,
      r = l.z5(e.x, e.y, this.cameraData.width, this.cameraData.height)
    let o,
      a = null
    this.cameraPosition.set(r.x, r.y, -1).unproject(n), this.forwardPosition.set(r.x, r.y, 1).unproject(n)
    const c = this.raycaster.picking.cast(
      this.cameraPosition,
      this.forwardPosition.clone().sub(this.cameraPosition).normalize(),
      i ? funcUtil.isModelColliderTarget : funcUtil.raycastVisible
    )[0]
    if (
      (c &&
        c.object instanceof ModelColliderTarget &&
        ((a = (c && c.point) || null),
        roomFunc.hasFloorId(c.object) ? (o = this.floorsData.getFloor(c.object.floorId)) : a && (o = this.floorsData.getClosestFloorAtHeight(a.y))),
      void 0 !== t)
    ) {
      this.cameraPosition.copy(this.cameraData.pose.position)
      const e = l.st(this.cameraData, r)
      if (this.viewmodeData.currentMode !== viewmodeEnum.Floorplan) {
        const i = f.n0(this.cameraPosition, e)
        this.targetPlane.set(Vectors.DOWN, t), (a = f.Fe(this.cameraPosition, i, this.targetPlane) || null)
      } else (e.y = t), (a = e)
    }
    const h = o ? o.index : -1
    return { position: a, floor: h, floorIndex: h }
  }
}
// const b = FloorCaster
// export default {
//   GetFloorIntersectCommand: GetFloorIntersectCommand,
//   default: b
// }
